package com.health;


import com.health.pojo.Product;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * ElasticsearchRestTemplate高亮查询
 */
@SpringBootTest
public class ElasticsearchRestTemplateHighlight {


    @Resource
    private ElasticsearchRestTemplate restTemplate;

    /**
     *  高亮查询-多字段
     *  动态传参-可传可不传可为null
     */
    @Test
    void test3(){
        //查询的参数
        String name="零食小吃";
        String merchant=null;

        //创建boolquery-多参数查询
        BoolQueryBuilder bool = new BoolQueryBuilder();
        //添加查询参数到boolquery
        if (StringUtils.hasText(name))
        bool.must(new MatchQueryBuilder("name",name));
        if (StringUtils.hasText(merchant))
        bool.must(new MatchQueryBuilder("merchant",merchant));

        //添加高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name").field("merchant")
                .preTags("<font color='red'>").postTags("</font>");

        //创建query请求
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(bool)
                .withHighlightBuilder(highlightBuilder)
                .build();

        //查询
        SearchHits<Product> searchHits = restTemplate.search(searchQuery, Product.class);

        //最终数据的product集合
        List<Product> productList=new ArrayList<>();
        //高亮添加到对象中
        for (SearchHit<Product> searchHit : searchHits) {
            //获取原来的内容
            Product product = searchHit.getContent();

            //获取高亮结果-需要判断否则字段为null时报索引越界异常
            //根据字段获取的高亮集合不为null,但是字段为空时,集合为空
            List<String> nameList = searchHit.getHighlightField("name");
            if (nameList.size()>0){
                String name_high = nameList.get(0);
                //添加到对象
                product.setName(name_high);
            }

            List<String> merchantList = searchHit.getHighlightField("merchant");
            if (merchantList.size()>0){
                String merchant_high = merchantList.get(0);
                //添加到对象
                product.setMerchant(merchant_high);
            }
            //添加到集合
            productList.add(product);
        }

        //最终数据遍历
        for (Product product : productList) {
            System.out.println(product);
        }

    }

    /**
     * 高亮查询-多字段
     */
    @Test
    void test2(){
        //查询字段
        String name="零食小吃";
        String merchant="三只松鼠";

        //多字段查询-boolquery
        BoolQueryBuilder bool = new BoolQueryBuilder();
        //添加查询参数
        bool.must(new MatchQueryBuilder("name",name));
        bool.must(new MatchQueryBuilder("merchant",merchant));

        //高亮添加
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        //链式语法添加多字段的高亮显示
        highlightBuilder.field("name").field("merchant")
                .preTags("<font color='red'>")
                .postTags("</font>");

        //创建query请求
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(bool)//携带请求参数
                .withHighlightBuilder(highlightBuilder)//携带高亮参数
                .build();

        //查询
        SearchHits<Product> searchHits = restTemplate.search(searchQuery, Product.class);

        List<Product> productList=new ArrayList<>();
        //遍历添加高亮
        for (SearchHit<Product> searchHit : searchHits) {
            //获取product
            Product product = searchHit.getContent();

            //获取高亮结果
            String name_high = searchHit.getHighlightField("name").get(0);
            String merchant_high = searchHit.getHighlightField("merchant").get(0);

            //设置高亮结果到product属性中
            product.setName(name_high);
            product.setMerchant(merchant_high);
            //修改后的对象添加到集合
            productList.add(product);
        }

        //遍历结果
        for (Product product : productList) {
            System.out.println(product);
        }

    }

    /**
     * 高亮查询-单字段
     */
    @Test
    void test1(){
        //查询字段
        String name="男衬衫";
        //单字段matchquery
        MatchQueryBuilder match = new MatchQueryBuilder("name",name);

        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        //给指定属性添加高亮字段,使用font标签可以让前端直接使用
        highlightBuilder.field("name").preTags("<font color='red'>").postTags("</font>");

        //query请求
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(match)//查询
                .withHighlightBuilder(highlightBuilder)//添加高亮
                .build();//创建请求

        //查询
        SearchHits<Product> searchHits = restTemplate.search(searchQuery, Product.class);

        List<Product> productList=new ArrayList<>();
        //遍历,添加高亮到product
        for (SearchHit<Product> searchHit : searchHits) {
            //将高亮添加到product中
            Product product = searchHit.getContent();

            //获取高亮字段
            String name_high = searchHit.getHighlightField("name").get(0);

            //设置product
            product.setName(name_high);
            //添加修改后的product到集合中
            productList.add(product);
        }

        //查看结果
        for (Product product : productList) {
            System.out.println(product);
        }
    }

}
